package main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;



public class KMPMatch {

	  private static String filename;
	  private static String file;
	  private static String FileA1;
	  private static String FileB1;
	  private static String pattern;
	  private static String[] contents;
	  private static String[] allFileNames;
	  private static HashMap <String, Integer> counts = new HashMap <String, Integer>(); 
	  private static int count =0;
	
	
	public static int KMPmatch(String text, String pattern) {
		   int[] fail = computeFailFunction(pattern);
		   int i = 0;
		   int j = 0;
		   while (i < text.length()) {
		     if (pattern.charAt(j) == text.charAt(i)) {
		       if (j == pattern.length() - 1)
		         return i - pattern.length() + 1; // match
		       i++;
		       j++;
		     } 
		     else if (j > 0)
		       j = fail[j - 1];
		     else
		       i++;
		   } 
		   return -1; // no match
		 }
		 public static int[] computeFailFunction(String pattern) {
		   int[] fail = new int[pattern.length()]; 
		   fail[0] = 0;
		   int j = 0;
		   int i = 1;
		   while (i < pattern.length()) {
		     if (pattern.charAt(j) == pattern.charAt(i)) { // j + 1 characters match
		       fail[i] = j + 1;
		       i++;
		       j++;
		     }
		     else if (j > 0) // j follows a matching prefix
		       j = fail[j - 1];
		     else { // no match
		       fail[i] = 0;
		       i++;
		     }
		   }
		   return fail;
		 }
		 
		 
		 public static void main(String[] filenames){
		         allFileNames=filenames;
		      try {
					file = readPhrases();
				} catch (IOException e1) {e1.printStackTrace();}
	
		      for (String filenm : filenames){
		       try {
		    	  // System.out.println(filenm);
		    	filename = filenm;
		    	//System.out.println(filenm);
				readLines(filenm);
		    	
				toFile();
			} catch (IOException e) {
			}
		       int i =0;
		       for(String s: contents){
		    	Scanner scan = new Scanner (file);
		    	while (scan.hasNext()){
		    		pattern = scan.nextLine();
		    	   if(KMPmatch(s, pattern) != -1){
		    		   //System.out.println("s: " +s + " pattern: " + pattern + " result: "+ KMPmatch(s, pattern) );
		    		   
		    		   if (counts.containsKey(pattern)){
		    			   int oldCount = counts.get(pattern);
		    			   counts.put(pattern, oldCount +1 );
		    		   }
		    		   else{
		    			   counts.put(pattern, 1 );
		    			   
		    		   }
		    		     i++;
		    	   }
		    	   if(KMPmatch(s, pattern) == -1 && !counts.containsKey(pattern)){ counts.put(pattern, 0);}
		      
		    	   }
		      }
		     
		      }
		    
		      Iterator iterator = counts.keySet().iterator();
		      
		      while (iterator.hasNext()) {
		         String key = iterator.next().toString();
		         String value = counts.get(key).toString();
		       
		         //System.out.println(key + " " + value);
		      }
		      
		      for(int i = 0; i <allFileNames.length; i++){
		    	  System.out.println(allFileNames[i]);
		      }
		    
		      
}
		 
		 public static String[] readLines(String filenames) throws IOException {
			 //System.out.println(filenames);
		
		        FileReader fileReader = new FileReader(filenames);
		        Scanner scan = new Scanner (fileReader);
		        List<String> lines = new ArrayList<String>();
		        String line = null;
		        while (scan.hasNext()) {
		        	line = scan.nextLine();
		            lines.add(line);
		        }
		        scan.close();
		       
		        contents=lines.toArray(new String[lines.size()]);
		        
		        try {printToFile();} catch (IOException e) {e.printStackTrace();}
		        return lines.toArray(new String[lines.size()]);
		    }
		 
		  private static String readPhrases() throws java.io.IOException{
				        StringBuffer fileData = new StringBuffer(1000);
				        BufferedReader reader = new BufferedReader(new FileReader("Phrases"));
				        char[] buf = new char[1024];
				        int numRead=0;
				        while((numRead=reader.read(buf)) != -1){
				            String readData = String.valueOf(buf, 0, numRead);
				            fileData.append(readData);
				            buf = new char[1024];
				        }
				        reader.close();
				        //System.out.println(fileData.toString());
				        return fileData.toString();
				    }
		  private static void toFile() {
			  try{
			  // Create file 
				  
			  FileWriter fstream = new FileWriter(filename + "-counts.txt");
			  BufferedWriter out = new BufferedWriter(fstream);
			  Iterator iterator = counts.keySet().iterator();
		      
		      while (iterator.hasNext()) {
		         String key = iterator.next().toString();
		         String value = counts.get(key).toString();
		       
		         out.write(key + " " + value +"\r\n" );
		      }
		      
			  //Close the output stream
			  out.close();
			  }catch (Exception e){//Catch exception if any
			  System.err.println("Error: " + e.getMessage());
			  }
			  
			  printSingleFile();
			  }
		  
		  
		private static void printSingleFile() {
			BufferedWriter out = null;
			  File f = new File(filename + "-counts-WITHOUT.txt");
			if(!f.exists()){
			try{
				  // Create file 
				  
				  
				  FileWriter fstream = new FileWriter(f);
				  out = new BufferedWriter(fstream);
				  Iterator iterator = counts.keySet().iterator();
			      
			      while (iterator.hasNext()) {
			         String key = iterator.next().toString();
			         String value = counts.get(key).toString();
			       
			         out.write(value + " " );
			        // System.out.print(value + " ");
			      }
				  
				  //Close the output stream
				  out.close();
			}
				  catch (Exception e){//Catch exception if any
				  System.err.println("Error: " + e.getMessage());
				  }
			}
			
			
		}
		
		public static void printToFile() throws IOException{
			
			int i =0;
			int j =1;
			int numRead = 0;
			int numRead2 = 0;
			
			String fileA = null;
			String fileB = null;
			
			char[] buf = new char[5000];
			char[] buf2 = new char[5000];
			
			BufferedReader reader = null;
			BufferedReader reader2 = null;
			
			StringBuffer fileData = new StringBuffer(10000);
			StringBuffer fileData2 = new StringBuffer(10000);
			
			if(allFileNames[i]!= null){reader = new BufferedReader(new FileReader(allFileNames[i]));
			if(allFileNames[j]!= null){reader2 = new BufferedReader(new FileReader(allFileNames[j]));
			
			while((numRead=reader.read(buf)) != -1){
				String readData = String.valueOf(buf, 0, numRead);
				fileData.append(readData);
		            buf = new char[1024];
		            fileA = fileData.toString();	
//		            
//		            reader = new BufferedReader(new FileReader(allFileNames[i])); 
		            i++;
			} 
			
			  while((numRead2=reader2.read(buf2)) != -1){
		            String readData2 = String.valueOf(buf2, 0, numRead2);
		            fileData2.append(readData2);
		            buf2 = new char[1024];
		            fileB = fileData2.toString();
		           
//		            reader2 = new BufferedReader(new FileReader(allFileNames[j])); 
		            j++;
			  }
			}
			}
			 
			//  System.out.println("FILE A: \n\n\n\n\n\n\n\n\n\n" + fileA.toString());
			 // System.out.println("FILE B: \n\n\n\n\n\n\n\n\n\n" +fileB.toString());

			
					
					calculateDifference(fileA, fileB);
		       
		        reader.close();
		        reader2.close();
		}
			 
		 
		private static void calculateDifference(String fileA, String fileB) {
			FileA1=fileA;
			FileB1= fileB;
			//System.out.println(fileA + "\n " + fileB);
			double squareRootA = 0.0, squareRootB = 0.0;
			double fileASum = 0.0;
			int fileBSum = 0; //works out the sum of all the a[i]*b[i]
			Scanner scan = new Scanner (fileA);
			Scanner scan2 = new Scanner (fileB);
			while(scan.hasNextInt()){
				while(scan2.hasNextInt()){
				int a = scan.nextInt();
				int b = scan2.nextInt();
				int mult = a*b;
				fileASum+= mult;
			}
			
				
				Scanner scan3 = new Scanner (fileA);
				Scanner scan4 = new Scanner (fileB);
				int fileASqr = 0;
				while(scan3.hasNextInt()){ //sum a[i]**2
					int a = scan3.nextInt();
					int square = a*a;
					fileASqr+= square;
				}
				int fileBSqr = 0; //sum b[i]**2
				while(scan4.hasNextInt()){
					int b = scan4.nextInt();
					int square = b*b;
					fileBSqr+= square;
				}
			
				squareRootA =  Math.sqrt(fileASqr);
				squareRootB =  Math.sqrt(fileBSqr);
				}


			double answer = fileASum /(squareRootA * squareRootB);
			System.out.println(FileA1 + " vs. " + FileB1 + "= "+ answer);
			//System.out.println(fileB);
		//	System.out.println(fileASum);
		//	System.out.println(answer);
			//System.out.println("done");
		}
			


			  
		  }
